package api

import (
	"errors"
	"github.com/globalsign/mgo"
	"jgt-oper/src/bll"
	"jgt-oper/src/context"
	"jgt-oper/src/schema"
	"jgt-oper/src/util"
	"strconv"
	"time"
)

// AEVController 移动端后台控制器
type AEVController struct {
	EVBll   *bll.EVisit            `inject:""`
	UserBll *bll.User              `inject:""`
	FVBll   *bll.FrequentlyVisitor `inject:""`
	ParkBll *bll.Park              `inject:""`
	EPBll   *bll.EnterprisePark    `inject:""`
}

// Create 创建来访
func (a *AEVController) Create(ctx *context.Context) error {
	ctx.WriteOperateLog("AEVController.Create", "服务平台-企业来访管理-创建来访记录")
	//	获取参数
	params := new(schema.EVCParams)
	if err := ctx.ParseJSON(params); err != nil {
		return ctx.ResErrBadRequest(err)
	}
	//	构造存储结构
	item := new(schema.EnterpriseVisit)
	item.ID = 0
	item.RecordID = util.UUID()
	item.Creator = ctx.GetUserID()
	item.Created = time.Now().Unix()
	item.Deleted = 0

	item.PersonnelName = params.PersonnelName
	item.ContractTel = params.ContractTel
	item.FromEnterprise = params.FromEnterprise
	//	来访单位id
	user, err := a.UserBll.Get(ctx.GetUserID())
	if err != nil && err != mgo.ErrNotFound {
		return ctx.ResErrInternalServer(err)
	}
	if err == mgo.ErrNotFound || user == nil {
		return ctx.ResErrBadRequest(errors.New("当前企业管理员的信息未找到"))
	}
	if user.EnterpriseID == "" {
		return ctx.ResErrBadRequest(errors.New("当前企业管理员的企业id未找到"))
	}
	item.VisitingEnterpriseID = user.EnterpriseID
	item.PersonnelTotal = params.PersonnelTotal
	item.MainContent = params.MainContent
	item.StartTime = params.StartTime
	item.EndTime = params.EndTime
	item.ParkNodeID = params.ParkNodeID
	item.SendTimes = 1
	item.Status = 1
	item.IsCome = 0

	//	存储
	err = a.EVBll.Create(item)
	if err != nil {
		return ctx.ResErrInternalServer(err)
	}
	//	添加常用访客
	if params.AddFrequent == 1 {
		fv := new(schema.FrequentlyItem)
		fv.Name = item.PersonnelName
		fv.Tel = item.ContractTel
		err := a.FVBll.Insert(ctx.GetUserID(), fv)
		if err != nil {
			return ctx.ResErrInternalServer(err)
		}
	}
	//	返回ok
	return ctx.ResOK()
}

// QueryFrequently 查询常用访客
func (a *AEVController) QueryFrequently(ctx *context.Context) error {
	ctx.WriteOperateLog("AEVController.QueryFrequently", "企业来访-查询常用访客")
	//	查询
	item, err := a.FVBll.Get(ctx.GetUserID())
	if err != nil || item == nil {
		return ctx.ResErrInternalServer(err)
	}
	resultList := make([]map[string]interface{}, 0)
	for _, value := range item.FrequentlyItems {
		tempMap := make(map[string]interface{})
		tempMap["personnel_name"] = value.Name
		tempMap["contract_tel"] = value.Tel
		resultList = append(resultList, tempMap)
	}

	return ctx.ResSuccess(resultList)
}

// QueryPage (移动端)查询企业来访列表
func (a *AEVController) QueryPage(ctx *context.Context) error {
	ctx.WriteOperateLog("AEVController.QueryPage", "企业来访-查询访客清单列表")
	params := new(schema.ApiEVQParams)
	params.LastID = ctx.QueryInt("id")
	if params.LastID <= 0 {
		params.LastID = 0
	}
	params.PageSize = ctx.QueryInt("pageSize")
	if params.PageSize <= 0 {
		params.PageSize = 10
	}
	params.PersonnelName = ctx.Query("personnel_name")
	params.IsCome = ctx.QueryInt("is_come")
	//	查询用户信息
	user, err := a.UserBll.Get(ctx.GetUserID())
	if err != nil {
		return ctx.ResErrInternalServer(errors.New("查询当前用户信息发生错误"))
	}
	//	用户所在企业的id
	params.EnterpriseID = user.EnterpriseID
	//	查询
	total, items, err := a.EVBll.QueryPage(params)
	if err != nil {
		return ctx.ResErrInternalServer(err)
	}
	//	组装返回数据
	timestamp := time.Now().Unix()
	list := make([]map[string]interface{}, 0)
	for _, item := range items {
		tempMap := make(map[string]interface{})
		tempMap["id"] = item.ID
		tempMap["record_id"] = item.RecordID
		tempMap["personnel_name"] = item.PersonnelName
		tempMap["contract_tel"] = item.ContractTel
		tempMap["visiting_enterprise_id"] = item.VisitingEnterpriseID
		tempMap["start_time"] = item.StartTime
		tempMap["end_time"] = item.EndTime
		tempMap["park_node_id"] = item.ParkNodeID
		//	构造访问单位门牌
		fullName, err := a.ParkBll.QueryFullName(item.ParkNodeID)
		if err != nil {
			return ctx.ResErrInternalServer(errors.New("获取访问单位门牌全名出错"))
		}
		tempMap["park_full_name"] = fullName
		//	到访状态
		tempMap["is_come"] = item.IsCome
		tempMap["status"] = 10 //	未逾期+未操作取消
		if item.Status == 1 && item.EndTime < timestamp {
			tempMap["status"] = 11 //	逾期
		} else if item.Status == 2 {
			tempMap["status"] = 12 //	操作取消
		}
		list = append(list, tempMap)
	}
	result := map[string]interface{}{
		"list": list,
		"pagination": map[string]interface{}{
			"total":    total,
			"current":  1,
			"pageSize": params.PageSize,
		},
	}

	return ctx.ResSuccess(result)
}

// QueryVisitDetail 查询来访详情
func (a *AEVController) QueryVisitDetail(ctx *context.Context) error {
	ctx.WriteOperateLog("AEVController.QueryVisitDetail", "企业来访-查询来访详情")
	recordID := ctx.Query("id")
	if recordID == "" {
		return ctx.ResErrBadRequest(errors.New("id参数错误"))
	}
	item, err := a.EVBll.Get(recordID)
	if err != nil {
		return ctx.ResErrInternalServer(err)
	}
	if item == nil {
		return ctx.ResErrInternalServer(errors.New("来访记录信息出现空指针"))
	}
	resultMap := make(map[string]interface{})
	resultMap["record_id"] = item.RecordID
	resultMap["personnel_name"] = item.PersonnelName
	resultMap["contract_tel"] = item.ContractTel
	resultMap["from_enterprise"] = item.FromEnterprise
	resultMap["personnel_total"] = item.PersonnelTotal
	resultMap["main_content"] = item.MainContent
	resultMap["start_time"] = item.StartTime
	resultMap["end_time"] = item.EndTime
	resultMap["park_node_id"] = item.ParkNodeID

	//	构造访问单位门牌
	fullName, err := a.ParkBll.QueryFullName(item.ParkNodeID)
	if err != nil {
		return ctx.ResErrInternalServer(errors.New("获取访问单位门牌全名出错"))
	}
	resultMap["park_full_name"] = fullName
	//	到访状态
	resultMap["is_come"] = item.IsCome
	resultMap["status"] = 10 //	未逾期+未操作取消
	timestamp := time.Now().Unix()
	if item.Status == 1 && item.EndTime < timestamp {
		resultMap["status"] = 11 //	逾期
	} else if item.Status == 2 {
		resultMap["status"] = 12 //	操作取消
	}
	return ctx.ResSuccess(resultMap)
}

// QueryDefaultPark 查询默认的当前用户的企业门牌全名
func (a *AEVController) QueryDefaultPark(ctx *context.Context) error {
	ctx.WriteOperateLog("AEVController.QueryDefaultPark", "企业来访-默认门牌信息")
	//	查询用户信息
	user, err := a.UserBll.Get(ctx.GetUserID())
	if err != nil {
		return ctx.ResErrInternalServer(err)
	}
	if user == nil {
		return ctx.ResErrInternalServer(errors.New("用户信息出现空指针"))
	}
	//	企业门牌信息
	epark, err := a.EPBll.Get(user.EnterpriseID)
	if err != nil {
		return ctx.ResErrInternalServer(err)
	}
	if epark == nil {
		return ctx.ResErrInternalServer(errors.New("企业门牌信息出现空指针"))
	}
	if len(epark.Nodes) == 0 {
		return ctx.ResErrBadRequest(errors.New("企业没有设置门牌"))
	}
	fullName, err := a.ParkBll.QueryFullName(epark.Nodes[0])
	if err != nil {
		return ctx.ResErrInternalServer(errors.New("查询门牌全名发生错误"))
	}
	result := make(map[string]interface{})
	result["park_name"] = fullName
	result["park_node_id"] = epark.Nodes[0]

	return ctx.ResSuccess(result)
}

// QueryDefaultNodes 查询默认节点(用于下拉框)
func (a *AEVController) QueryDefaultNodes(ctx *context.Context) error {
	ctx.WriteOperateLog("AEVController.QueryDefaultNodes", "企业来访-查询指定节点的子节点")
	//	查询用户信息
	user, err := a.UserBll.Get(ctx.GetUserID())
	if err != nil {
		return ctx.ResErrInternalServer(err)
	}
	if user == nil {
		return ctx.ResErrInternalServer(errors.New("用户信息出现空指针"))
	}
	//	企业门牌信息
	epark, err := a.EPBll.Get(user.EnterpriseID)
	if err != nil {
		return ctx.ResErrInternalServer(err)
	}
	if epark == nil {
		return ctx.ResErrInternalServer(errors.New("企业门牌信息出现空指针"))
	}
	if len(epark.Nodes) == 0 {
		return ctx.ResErrBadRequest(errors.New("企业没有设置门牌"))
	}
	firstNode, err := a.ParkBll.Get(epark.Nodes[0])
	if err != nil {
		return ctx.ResErrInternalServer(err)
	}
	if firstNode == nil {
		return ctx.ResErrInternalServer(errors.New("门牌节点空指针"))
	}
	resultMap := make(map[string]interface{})
	//	默认值
	s := make([]map[string]interface{}, 0)
	resultMap["yuanqu"] = s
	resultMap["quyu"] = s
	resultMap["loudong"] = s
	resultMap["danyuan"] = s
	resultMap["louceng"] = s
	resultMap["menpai"] = s
	var tempLevelCode string
	for i := len(firstNode.LevelCode); i > 0; i -= 2 {
		regexStr := "^" + firstNode.LevelCode[:i-2] + "..$"
		tempLevelCode = firstNode.LevelCode[:i]
		items, err := a.ParkBll.QueryNodesByLevelCode(regexStr)
		if err != nil {
			return ctx.ResErrInternalServer(err)
		}
		var nodeName string
		switch i {
		case 2:
			nodeName = "yuanqu"
		case 4:
			nodeName = "quyu"
		case 6:
			nodeName = "loudong"
		case 8:
			nodeName = "danyuan"
		case 10:
			nodeName = "louceng"
		case 12:
			nodeName = "menpai"
		}
		tempList := make([]map[string]interface{}, 0)
		for i, item := range items {
			itemMap := make(map[string]interface{})
			itemMap["record_id"] = item.RecordID
			itemMap["node_type"] = item.Type
			itemMap["node_name"] = item.Name
			itemMap["key"] = i
			if item.LevelCode == tempLevelCode {
				itemMap["default"] = item.RecordID
			}
			tempList = append(tempList, itemMap)
		}
		resultMap[nodeName] = tempList
	}
	return ctx.ResSuccess(resultMap)
}

// QueryChildrenNodes 查询默认节点(用于下拉框)
func (a *AEVController) QueryChildrenNodes(ctx *context.Context) error {
	ctx.WriteOperateLog("AEVController.QueryChildrenNodes", "企业来访-查询指定节点的子节点22")
	//	获取参数(节点的record_id)
	nodeID := ctx.Query("id")

	if nodeID == "" {
		return ctx.ResErrBadRequest(errors.New("id参数不能为空"))
	}

	firstNode, err := a.ParkBll.Get(nodeID)
	if err != nil {
		return ctx.ResErrInternalServer(err)
	}
	if firstNode == nil {
		return ctx.ResErrInternalServer(errors.New("门牌节点空指针"))
	}
	resultMap := make(map[string]interface{})

	for i := 0; 12-len(firstNode.LevelCode)-i > 0; i += 2 {
		regexStr := "^" + firstNode.LevelCode + "(01){" + strconv.Itoa(i/2) + "}" + "..$"
		items, err := a.ParkBll.QueryNodesByLevelCode(regexStr)
		if err != nil {
			return ctx.ResErrInternalServer(err)
		}
		var nodeName string
		switch i + len(firstNode.LevelCode) + 2 {
		case 2:
			nodeName = "yuanqu"
		case 4:
			nodeName = "quyu"
		case 6:
			nodeName = "loudong"
		case 8:
			nodeName = "danyuan"
		case 10:
			nodeName = "louceng"
		case 12:
			nodeName = "menpai"
		}
		tempList := make([]map[string]interface{}, 0)
		for i, item := range items {
			itemMap := make(map[string]interface{})
			itemMap["record_id"] = item.RecordID
			itemMap["node_type"] = item.Type
			itemMap["node_name"] = item.Name
			itemMap["key"] = i
			tempList = append(tempList, itemMap)
		}
		resultMap[nodeName] = tempList
	}
	return ctx.ResSuccess(resultMap)
}

// QueryParkNodes 查询指定门牌的所有直接子节点
func (a *AEVController) QueryParkNodes(ctx *context.Context) error {
	ctx.WriteOperateLog("AEVController.QueryParkNodes", "企业来访-查询指定节点的子节点")
	//	获取参数(节点的record_id)
	nodeID := ctx.Query("id")
	nodeType := ctx.QueryInt("parent_node_type")
	if nodeType != 10 && nodeType != 20 && nodeType != 30 && nodeType != 40 && nodeType != 50 && nodeType != 60 {
		return ctx.ResErrBadRequest(errors.New("parent_node_type错误"))
	}
	if nodeID == "" {
		return ctx.ResErrBadRequest(errors.New("id参数不能为空"))
	}
	nodes, err := a.ParkBll.QueryDirectChildrenNodes(nodeID)
	if err != nil {
		return ctx.ResErrInternalServer(errors.New("查询直接子节点出错"))
	}
	list := make([]map[string]interface{}, 0)
	nType := ""
	switch nodeType + 10 {
	case 10:
		nType = "yuanqu"
	case 20:
		nType = "quyu"
	case 30:
		nType = "loudong"
	case 40:
		nType = "danyuan"
	case 50:
		nType = "louceng"
	case 60:
		nType = "menpai"
	}
	for i, node := range nodes {
		tempMap := make(map[string]interface{})
		tempMap["record_id"] = node.RecordID
		tempMap["node_name"] = node.Name
		tempMap["node_type"] = node.Type
		tempMap["key"] = i
		list = append(list, tempMap)
	}
	resultMap := make(map[string]interface{})
	resultMap[nType] = list
	return ctx.ResSuccess(resultMap)
}

// Cancel (移动端)作废来访
func (a *AEVController) Cancel(ctx *context.Context) error {
	ctx.WriteOperateLog("AEVController.Cancel", "企业来访-取消作废来访")
	//	获取取消的来访记录的record_id
	recordID := ctx.Param("id")
	item, err := a.EVBll.Get(recordID)
	if err != nil || item == nil {
		return ctx.ResErrInternalServer(errors.New("检查当前来访记录发生错误"))
	}
	//	检查符合取消的条件
	timestamp := time.Now().Unix()
	if item.EndTime > timestamp && item.Status == 1 && item.IsCome == 0 {
		err = a.EVBll.Cancel(recordID)
		if err != nil {
			return ctx.ResErrInternalServer(err)
		}
	} else if item.EndTime <= timestamp {
		return ctx.ResErrBadRequest(errors.New("逾期，不能操作取消"))
	}
	return ctx.ResOK()
}

// Resend 重发短信
func (a *AEVController) Resend(ctx *context.Context) error {
	ctx.WriteOperateLog("AEVController.Resend", "企业来访--重发短信")
	//	来访记录的record_id
	recordID := ctx.Param("id")
	item, err := a.EVBll.Get(recordID)
	if err != nil || item == nil {
		return ctx.ResErrInternalServer(errors.New("检查当前来访记录发生错误"))
	}
	//	检查符合取消的条件
	timestamp := time.Now().Unix()
	if item.EndTime > timestamp && item.Status == 1 && item.IsCome == 0 {
		err = a.EVBll.Resend(recordID)
		if err != nil {
			return ctx.ResErrInternalServer(err)
		}
		//	TODO 执行发送短信
	} else {
		return ctx.ResErrBadRequest(errors.New("该来访不符合重发条件"))
	}
	return ctx.ResOK()
}
